<template>
  <div>
    <el-button
      type="primary"
      style="margin: 10px 10px 10px 10px"
      @click="showAddDialog"
    >
      新增</el-button
    >
    <TreeTable
      :value="treeTableData"
      :paginator="true"
      :resizableColumns="true"
      columnResizeMode="fit"
      :rows="rows"
    >
      <Column field="name" header="菜单名称" :expander="true"></Column>
      <Column header="类型">
        <template #body="slotProps">
          <span>{{ menuTypeMap[slotProps.node.data.menuType] || "" }}</span>
        </template>
      </Column>
      <Column header="是否显示">
        <template #body="slotProps">
          <span>{{ slotProps.node.data.display ? "是" : "否" }}</span>
        </template>
      </Column>
      <Column headerStyle="width: 10rem" header="操作">
        <template #body="slotProps">
          <div class="flex flex-wrap gap-2">
            <el-link
              type="primary"
              :underline="false"
              @click="edit(slotProps.node.key)"
              icon="el-icon-view"
              >查看</el-link
            >
            <el-link
              type="primary"
              :underline="false"
              @click="showEditDialog(slotProps.node.key)"
              icon="el-icon-edit"
              v-if="slotProps.node.data.menuType==0||slotProps.node.data.menuType==1"
              >编辑</el-link
            >

            <el-link
              type="primary"
              :underline="false"
              @click="showEditButtonDialog(slotProps.node.key)"
              icon="el-icon-edit"
              v-if="slotProps.node.data.menuType==2"
              >编辑</el-link
            >

            <el-link
              type="primary"
              :underline="false"
              @click="showbuttonDialog(slotProps.node.key)"
              v-if="slotProps.node.data.menuType === 1"
              icon="el-icon-edit"
              >配置按钮</el-link
            >
            <el-link
              type="primary"
              :underline="false"
              @click="deleteItem(slotProps.node.key)"
              icon="el-icon-delete"
              >删除</el-link
            >
          </div>
        </template>
      </Column>
    </TreeTable>

    <el-dialog
      :visible.sync="dialogVisible"
      :title="dialogMenuTitle"
      width="30%"
    >
      <el-form
        :model="formData"
        ref="dataForm"
        label-width="80px"
        :rules="formRules"
      >
        <el-form-item label="名称" required prop="name">
          <el-input
            v-model="formData.name"
            @input="updateIdentifier"
          ></el-input>
        </el-form-item>
        <el-form-item label="唯一标识" required prop="identifier">
          <el-input v-model="formData.identifier"></el-input>
        </el-form-item>
        <el-form-item label="类型" required>
          <el-select v-model="formData.type">
            <el-option label="目录" value="0"></el-option>
            <el-option label="菜单" value="1"></el-option>
          </el-select>
        </el-form-item>
        <el-form-item label="上级菜单" required v-if="formData.type === '1'">
          {{ checkedTreeData.label }}
          <Tree
            :value="selectTreeData"
            selectionMode="single"
            :filter="true"
            filterMode="lenient"
            :selectionKeys.sync="selectedKey2"
            :metaKeySelection="false"
            @node-select="onNodeSelect"
            @node-unselect="onNodeUnselect"
          ></Tree>
        </el-form-item>
        <el-form-item label="排序">
          <el-input
            v-model="formData.sortOrder"
            type="number"
            :min="1"
          ></el-input>
        </el-form-item>
        <el-form-item label="是否显示" required>
          <el-radio-group v-model="formData.isVisible">
            <el-radio label="true">是</el-radio>
            <el-radio label="false">否</el-radio>
          </el-radio-group>
        </el-form-item>
        <el-form-item label="菜单URL" required v-if="formData.type === '1'">
          <el-input v-model="formData.menuUrl"></el-input>
        </el-form-item>
        <el-form-item label="图标">
          <span :class="selectedIconStyle" style="font-size: 18px"></span>
          <br v-if="selectedIconStyle" />
          <el-button type="primary" round @click="showIconDialog"
            >配置图标</el-button
          >
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="resetForm">取消</el-button>
        <el-button type="primary" @click="saveForm">保存</el-button>
      </div>
    </el-dialog>
    <el-dialog :visible.sync="dialogIconVisible">
      <div class="icons-container">
        <div class="grid">
          <div
            v-for="item of elementIcons"
            :key="item"
            @click="selectIcon(item)"
          >
            <el-tooltip placement="top">
              <div slot="content">
                {{ generateElementIconCode(item) }}
              </div>
              <div class="icon-item">
                <i :class="'el-icon-' + item" />
                <span>{{ item }}</span>
              </div>
            </el-tooltip>
          </div>
        </div>
      </div>
    </el-dialog>
    <el-dialog
    title="配置按钮"
    :visible.sync="dialogButtonVisible"
    width="30%">
    <el-form :model="formData" :rules="formRules" ref="dataForm" label-width="120px">
      <el-form-item label="关联菜单" required prop="relatedMenu">
        <el-input v-model="formData.relatedMenu" placeholder="请输入关联菜单" :disabled="true"></el-input>
      </el-form-item>
      <el-form-item label="按钮名称" required prop="name">
        <el-input v-model="formData.name" placeholder="请输入按钮名称"  clearable></el-input>
      </el-form-item>
      <el-form-item label="唯一性标识" required prop="identifier">
        <el-input v-model="formData.identifier" placeholder="请输入唯一性标识" clearable></el-input>
      </el-form-item>
      <el-form-item label="排序">
        <el-input v-model.number="formData.sortOrder" type="number" :min="0" placeholder="请输入排序"></el-input>
      </el-form-item>
      <el-form-item label="是否显示">
        <el-radio-group v-model="formData.isVisible">
          <el-radio label="true">是</el-radio>
          <el-radio label="false">否</el-radio>
        </el-radio-group>
      </el-form-item>
    </el-form>
    <div slot="footer" class="dialog-footer">
      <el-button @click="dialogButtonVisible = false">取消</el-button>
      <el-button type="primary" @click="saveButton">保存</el-button>
    </div>
  </el-dialog>
  </div>
</template>
<script>
import { getTreeMenus, create,update, deleteMenu, getById } from "@/api/menu";
import TreeTable from "primevue/treetable";
import Column from "primevue/column"; // 导入Column组件
import Tree from "primevue/tree";
import elementIcons from "./element-icons";
import pinyin from "js-pinyin";
import findNodeById from '@/utils/treeHelper'
export default {
  components: {
    TreeTable,
    Column,
    Tree,
  },
  data() {
    return {
      selectedIconStyle: "",
      elementIcons,
      where: {},
      rows: 5,
      dialogButtonVisible:false,
      dialogIconVisible: false,
      dialogMenuTitle: "新增",
      dialogVisible: false,
      doAction:'add',
      selectedKey2: null,
      formData: {
        id:null,
        name: "",
        relatedMenu:"",
        parentId:null,
        identifier: "",
        permission: "",
        type: "0",
        sortOrder: 1,
        isVisible: 'true',
        menuUrl: "",
        meta: {
          title: '',
          icon: '',
        }
      },
      formRules: {
        name: [{ required: true, message: "请输入名称", trigger: "blur" }],
        identifier: [
          { required: true, message: "请输入唯一标识", trigger: "blur" },
          { validator: this.validateIdentifier, trigger: "blur" },
        ],
      },
      selectTreeData: [],
      checkedTreeData: {},
      treeTableData: [],
      menuTypeMap: {
        0: "目录",
        1: "菜单",
        2: "按钮",
      },
    };
  },
  mounted() {
    this.loadTreeMenus();
  },
  methods: {
    resetForm() {
      this.dialogVisible=false;
      this.dialogIconVisible = false;
      this.resetFormData();
    },
    validateIdentifier(rule, value, callback) {
      // 使用正则表达式检查输入是否只包含英文字符和数字
      const pattern = /^[a-zA-Z0-9-]+$/;
      if (pattern.test(value)) {
        callback(); // 验证通过
      } else {
        callback(new Error("唯一标识只能包含英文字符、数字和短划线(-)"));
      }
    },
    showEditButtonDialog(id){
      this.dialogButtonVisible=true;
      this.doAction='update';
      getById(id).then(res=>{
      this.setformData(res);
      }).catch(error=>this.$message.error(error))
    },
    showbuttonDialog(id){
      this.dialogButtonVisible=true;
      this.doAction='add';
      this.resetForm();
      getById(id).then(res=>{
        this.formData.parentId=res.id;
        this.formData.relatedMenu=res.name;
      }).catch(error=>{
        this.$message.error(error);
      });
    },
    deleteItem(id){
      deleteMenu(id).then(res=>{
        this.$message({
            message: '删除成功',
            type: 'success'
        });
        this.loadTreeMenus();
        this.dialogVisible=false;
      }).catch((error)=>{
        this.$message.error(error);
      })
    },
    saveButton(){
      this.formData.type=2;
      this.saveForm();
    },
    saveForm() {
      this.$refs.dataForm.validate((valid) => {
        if (valid) {
          if (this.formData.type === "1" && !this.checkedTreeData.key) {
            this.$message.error("请选择【上级菜单】");
            return;
          }
          if (this.formData.type === "1" && this.formData.menuUrl==='') {
            this.$message.error("请输入【菜单URL】");
            return;
          }
          const menudata = this.buildMenuData();
          if(this.doAction=='add'){
            create(menudata)
              .then((responseData) => {
                  this.$message({
                      message: '新增成功',
                      type: 'success'
                      });
                  this.loadTreeMenus();
                  this.resetFormData();
                  this.dialogVisible=false;
                  this.dialogButtonVisible=false;
              })
              .catch((error) => {
                // 保存失败，处理错误信息
                this.$message.error(error);
              });
          } else {
            // 表单验证失败，不执行保存逻辑
          }
          if(this.doAction=='update'){
            update(menudata.id,menudata).then(res=>{
              this.$message({
                      message: '编辑成功',
                      type: 'success'
                      });
                this.loadTreeMenus();
                this.resetFormData();
                this.dialogVisible=false;
                this.dialogButtonVisible=false;
            }).catch((error) => {
                // 保存失败，处理错误信息
                this.$message.error(error);
              });
          }
      }
      });
    },
    buildMenuData() {
      return {
        id: this.formData.id,
        name: this.formData.name,
        code: this.formData.identifier,
        menuType: this.formData.type,
        parentId: this.formData.type == "0" ? null : this.checkedTreeData.key||this.formData.parentId,
        order: this.formData.sortOrder,
        display: this.formData.isVisible,
        routerComponent:
          this.formData.type == "0" ? "LAYOUT" : this.formData.menuUrl,
        routerName: this.formData.identifier,
        routerPath: "/" + this.formData.identifier,
        permission:this.formData.identifier,
        meta: {
          title: this.formData.name,
          icon: this.selectedIconStyle,
        },
      };
    },
    updateIdentifier() {
      this.formData.identifier = pinyin.getFullChars(this.formData.name);
    },
    selectIcon(iconName) {
      this.selectedIconStyle = `el-icon-${iconName}`;
      this.dialogIconVisible = false;
    },
    generateElementIconCode(symbol) {
      return `<i class="el-icon-${symbol}" />`;
    },
    showIconDialog() {
      this.dialogIconVisible = true;
    },
    onNodeSelect(node) {
      this.checkedTreeData = node;
    },
    onNodeUnselect(node) {
      console.log("onNodeUnselect", node);
    },
    showAddDialog() {
      this.dialogVisible = true;
      this.doAction='add';
    },
    showEditDialog(id) {
      this.dialogVisible = true;
      this.dialogMenuTitle = "编辑";
      this.doAction='update';
      getById(id).then(res=>{
      this.setformData(res);
      debugger;
      }).catch(error=>this.$message.error(error))
    },
    loadTreeMenus() {
      getTreeMenus(this.where)
        .then((res) => {
          this.treeTableData = this.transformTableData(res);
          this.selectTreeData = this.transformSelectTreeData(res);
        })
        .catch((error) => {
          this.$message.error(error);
        });
    },
    transformTableData(originalData) {
      return originalData.map((item) => {
        let transformedItem = {
          key: item.id,
          id:  item.id,
          data: {
            name: item.name,
            menuType: item.menuType,
            parentId: item.parentId,
            display: item.display,
            icon: item.meta?.icon,
          },
        };
        if (item.children && item.children.length > 0) {
          transformedItem.children = this.transformTableData(item.children);
        }
        return transformedItem;
      });
    },
    transformSelectTreeData(originalData) {
      return originalData
        .filter((item) => item.menuType !== 2) // 过滤掉 menuType 等于 2 的项
        .map((item) => {
          let transformedItem = {
            key: item.id,
            id:item.id,
            label: item.name,
            icon: item.meta?.icon,
            data: item.menuType,
          };
          if (item.children && item.children.length > 0) {
            transformedItem.children = this.transformSelectTreeData(
              item.children
            );
          }
          return transformedItem;
        });
    },
    edit(key) {
      console.log(key);
    },
    loadLocalhostData() { // 测试用
      fetch("/json/treeTableDemo.json")
        .then((res) => res.json())
        .then((d) => {
          this.treeTableData = d.root;
        })
        .catch((error) => console.error("Error fetching data: ", error));
    },
    // 重置 formData 到初始状态
    resetFormData() {
      this.formData.id = null;
      this.formData.parentId=null;
      this.formData.name = "";
      this.formData.identifier = "";
      this.formData.permission = "";
      this.formData.type = "0";
      this.formData.sortOrder = 1;
      this.formData.isVisible = 'true';
      this.formData.menuUrl = "";
    },
    setformData(responseData){
      this.formData.id = responseData.id;
      this.checkedTreeData.key=responseData.parentId;
      this.formData.parentId=responseData.parentId;
      this.formData.name = responseData.name;
      this.formData.identifier = responseData.code;
      this.formData.permission = responseData.permission;
      this.formData.type =responseData.menuType.toString();
      this.formData.sortOrder =responseData.order;
      this.formData.isVisible = responseData.display.toString();
      this.formData.menuUrl = responseData.routerComponent;
      this.formData.meta.title=responseData.meta?.title;
      this.formData.meta.icon=responseData.meta?.icon;
      this.selectedIconStyle=responseData.meta?.icon;
      var node= findNodeById(this.treeTableData,this.parentId);
      this.formData.relatedMenu=node.name;
      this.checkedTreeData.label=node.name;

    }
  },
};
</script>
<style lang="scss" scoped>
.icons-container {
  margin: 10px 20px 0;
  overflow: hidden;
  .grid {
    position: relative;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(120px, 1fr));
  }
  .icon-item {
    margin: 20px;
    height: 85px;
    text-align: center;
    width: 100px;
    float: left;
    font-size: 30px;
    color: #24292e;
    cursor: pointer;
  }

  span {
    display: block;
    font-size: 16px;
    margin-top: 10px;
  }

  .disabled {
    pointer-events: none;
  }
}
.p-treetable .p-treetable-tbody > tr > td {
  text-align: left;
  padding: 0.5rem 0.5rem;
}
.p-treetable .p-treetable-thead > tr > th {
  text-align: left;
  padding: 1rem 1rem;
}
</style>
